package org.lztvn.elearning.front_controllers;


import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.apache.commons.io.IOUtils;
import org.lztvn.elearning.controllers.CourseController;
import org.lztvn.elearning.entities.Category;
import org.lztvn.elearning.entities.Command;
import org.lztvn.elearning.entities.CommandeLine;
import org.lztvn.elearning.entities.Contact;
import org.lztvn.elearning.entities.Content;
import org.lztvn.elearning.entities.Product;
import org.lztvn.elearning.entities.Unit;
import org.lztvn.elearning.entities.User;
import org.lztvn.elearning.service.ICategryService;
import org.lztvn.elearning.service.ICommandLineService;
import org.lztvn.elearning.service.ICommandeService;
import org.lztvn.elearning.service.IContactService;
import org.lztvn.elearning.service.IContentService;
import org.lztvn.elearning.service.ICourseService;
import org.lztvn.elearning.service.IQuestionService;
import org.lztvn.elearning.service.IUnitService;
import org.lztvn.elearning.service.IUserService;
import org.lztvn.elearning.service.JsonResponse;
import org.lztvn.elearning.service.Utility;
import org.lztvn.elearning.validation.UserValidation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.support.RequestContextUtils;

import sun.tools.jar.CommandLine;

@Controller
@RequestMapping(value = "/lstcourses")
@SessionAttributes("userFLogin")
public class CourseFrontController extends CourseController {
	@Autowired
	ICourseService serviceCor;
	@Autowired
	ICategryService serviceCat;
	@Autowired
	IUserService serviceUser;
	@Autowired
	IContentService serviceContent;
	@Autowired
	IUnitService serviceUnit;
	@Autowired
	IQuestionService serviceQuest; 
	@Autowired
	ICommandeService  serviceCommand;
	@Autowired
	ICommandLineService serviceCml;
	
	Utility util;
	JsonResponse jresp;
	
	private void init() {
		ApplicationContext context = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		this.util = (Utility) context.getBean("util");
		this.jresp = (JsonResponse) context.getBean("json");
	}

	@RequestMapping(value = "/index", method = RequestMethod.GET)
	public ModelAndView index(Model model) {
		// model.addAttribute("courses", serviceCor.listCourse());
		model.addAttribute("courses", serviceCor.listCourseInHome());
		model.addAttribute("categoris", serviceCat.listCatInHome());
		model.addAttribute("users", serviceUser.listTeacher());
		// List<Content> contents = serviceContent.listConType("banner");
		// List<String> urlPhotoList = null ;
		// for(Content c:contents){
		// String urlPhoto = "photoCon?idCon="+c.getIdContent();
		// urlPhotoList.add(urlPhoto);
		// }
		model.addAttribute("contents", serviceContent.listConType("banner"));
		model.addAttribute("middle_content_list", serviceContent.listConType("middle_content"));

		Content con = (Content) serviceContent.listConType("middle_content")
				.get(0);
		model.addAttribute("content_middle", con);
		model.addAttribute("path", "home");
		return new ModelAndView("lstcourses");
	}

	@RequestMapping(value = "photoUser", produces = MediaType.IMAGE_JPEG_VALUE)
	@ResponseBody
	public byte[] photoUser(Long idUser) throws IOException {
		User u = serviceUser.getUser(idUser);
		File f = new File(System.getProperty("java.io.tmpdir") + "/USER_" + idUser
				+ "_" + u.getPhoto());
		return IOUtils.toByteArray(new FileInputStream(f));
	}

	
	@RequestMapping(value = "photoCat", produces = MediaType.IMAGE_JPEG_VALUE)
	@ResponseBody
	public byte[] photoCat(Long idCat) throws IOException {
		Category c = serviceCat.getCategory(idCat);
		return IOUtils.toByteArray(new ByteArrayInputStream(c.getPhoto()));
	}
//	@RequestMapping(value = "photoUser", produces = MediaType.IMAGE_JPEG_VALUE)
//	@ResponseBody
//	public byte[] photoUser(Long idUser) throws IOException {
//		User u = serviceUser.getUser(idUser);
//		return IOUtils.toByteArray(new ByteArrayInputStream(u.getPhoto()));
//	}

	@RequestMapping(value = "photoCon", produces = MediaType.IMAGE_JPEG_VALUE)
	@ResponseBody
	public byte[] photoCon(Long idCon) throws IOException {
		Content c = serviceContent.getContent(idCon);
		return IOUtils.toByteArray(new ByteArrayInputStream(c.getPhoto()));
	}

	@RequestMapping(value = "/course")
	public ModelAndView viewCourse(Long idCor, Model model) {
		Product c = serviceCor.getCourse(idCor);
		model.addAttribute("course", c);
		model.addAttribute("commandeLine", new CommandeLine());
		List<Unit> lstu = serviceUnit.listUnitByCourseId_bis(idCor);
		model.addAttribute("list_unit", lstu);
		
		return new ModelAndView("course");
	}
	
	@RequestMapping(value = "/unit/{idu}/{idc}")
	public ModelAndView viewUnit(@PathVariable Long idu,@PathVariable Long idc, Model model) {
		Unit u = serviceUnit.getUnit(idu);
		model.addAttribute("unit", u);
		Product c = serviceCor.getCourse(idc);
		model.addAttribute("course", c);
		
		model.addAttribute("listquest", serviceQuest.getlistQuestionbyTestId(idu));
		return new ModelAndView("unit");
	}

	@RequestMapping(value = "/watch_video",method = RequestMethod.POST)
	public ModelAndView flogin(Model model,WebRequest webRequest,HttpSession session, 
			                  final RedirectAttributes redirectAttributes) {
		Long idCourse = Long.valueOf(webRequest.getParameter("idCourse"));
		
		redirectAttributes.addFlashAttribute("idCourse", idCourse);
		
		return new ModelAndView("redirect:login");
	}



	@RequestMapping(value = "/welcome")
	public ModelAndView welcome(Model model, HttpSession session) {
		init();
		if (!util.checkFrontSession(session) == true) {
			return new ModelAndView("redirect:login");
		}
		model.addAttribute("user", new User());
		return new ModelAndView("welcome");
	}
	
	@RequestMapping(value = "/login")
	public String login(Model model, HttpSession session) {
		//, @ModelAttribute("idCourse") final Long idCourse
		init();
		if (util.checkFrontSession(session) == true) {
			return ("welcome");
		}
		model.addAttribute("user", new User());
		return ("flogin");
	}

	// authentication
	@RequestMapping(value = "/authen", method = RequestMethod.POST)
	public String login(String username, String password, ModelMap model,
			HttpServletRequest request,WebRequest webRequest, RedirectAttributes redirectAttributes,@Valid @ModelAttribute("user") User user, BindingResult result) throws IOException {
		if (serviceUser.login(username, password).size() > 0) {
			User u = serviceUser.getUserByUsername(username);
			model.addAttribute("userFLogin", u);
			request.getSession().setAttribute("userFLogin", u);
			String idCourse = webRequest.getParameter("idCourse");
			if(idCourse==null||idCourse=="")
		   	  return ("redirect:welcome");
			else{
				Product c = serviceCor.getCourse( Long.parseLong(idCourse, 10));
				Integer nbviews = 0;
				try {
					nbviews= c.getNbview();	
					if(nbviews.equals(null))
					  nbviews = 0;	
				} catch (Exception e) {
					nbviews =0;
				}
				
				nbviews+=1;
				c.setNbview(nbviews);
				serviceCor.modifierCourse(c);
				List<Unit> lstu = serviceUnit.listUnitByCourseId_bis(Long.parseLong(idCourse));
				model.addAttribute("list_unit", lstu);
				
				model.addAttribute("course", c);
				model.addAttribute("idCourse_video", Long.parseLong(idCourse, 10));
				
				
				redirectAttributes.addAttribute("idCourse_video", Long.parseLong(idCourse, 10));
				
				return ("course");
			}
		} else {
			model.addAttribute("message", "Sorry, username or password error");
			return ("redirect:login");
		}
	}

	
	@RequestMapping(value = "/register")
	public ModelAndView register(Model model,HttpServletRequest request, HttpServletResponse response) {
//		LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
//		localeResolver.setLocale(request, response, StringUtils.parseLocaleString("jp"));
		model.addAttribute("user", new User());
		return new ModelAndView("register");
	}
	
	
	@RequestMapping(value = "/about", method = RequestMethod.GET)
    public ModelAndView about(Model model){
		Content about = (Content) serviceContent.listConType("about")
				.get(0);
		Content text_about_right = (Content) serviceContent.listConType("text_about_right")
				.get(0);
		Content text_about_bottom = (Content) serviceContent.listConType("text_about_bottom")
				.get(0);
		model.addAttribute("about", about);
		model.addAttribute("text_about_right", text_about_right);
		model.addAttribute("text_about_bottom", text_about_bottom);
		model.addAttribute("courses", serviceCor.listCourseInHome());
    	return new ModelAndView("about");
    }
	

	
	
	@RequestMapping(value = "/allcourses")
	public ModelAndView allcourses(Integer level,Model model, HttpSession session) {
		model.addAttribute("courses", serviceCor.listCourseByLevel(level));
		return new ModelAndView("allcourses");
	}

	@RequestMapping(value = "/registration", method = RequestMethod.POST)
	public String registration(@Valid User u, BindingResult bindingResult,
			Model model, MultipartFile file) throws IOException {
		 UserValidation userValidator = new UserValidation(serviceUser);
	     userValidator.validate(u, bindingResult);
		if (bindingResult.hasErrors()) {
			return ("register");
		}

		if (!file.isEmpty()) {
			String path = System.getProperty("java.io.tmpdir");
			u.setPhoto(file.getOriginalFilename());
			Long idU = null;
			idU = serviceUser.addUser(u);
			file.transferTo(new File(path + "/" + "USER_" + idU + "_"
					+ file.getOriginalFilename()));
		} else {
				serviceUser.addUser(u);
		}
		
        model.addAttribute("successRegister", "Registration successfull, you will receive the link to validate your email, Thank you !");
	
		return "register_succes";
	}
	
	
	@SuppressWarnings({ "null", "unchecked" })
	@RequestMapping(value = "/toBasket",method = RequestMethod.POST)
	public String command(Model model,WebRequest webRequest,HttpSession session, HttpServletRequest request,
			                  final RedirectAttributes redirectAttributes) throws IOException {
			Integer qty = Integer.valueOf(webRequest.getParameter("qty"));
			Long idCourse = Long.valueOf(webRequest.getParameter("idCourse"));

			model.addAttribute("qty", qty);	
			model.addAttribute("idCourse", idCourse);	
		
    		Product p = serviceCor.getCourse(idCourse);
			Hashtable<Product, Integer>  lstprob =  new Hashtable<Product, Integer>();
			boolean somethinginbasket = false;
			try {
				  lstprob = (Hashtable<Product, Integer>)session.getAttribute("basket");
				  if(lstprob.size()>0){
					  somethinginbasket = true;
				  }
			} catch (Exception e) {
				somethinginbasket = false;
			}
			
			
			if(!somethinginbasket){ 	
				Hashtable<Product, Integer>  lstprod = new Hashtable<Product, Integer>();
				lstprod.put(p, qty);
				request.getSession().setAttribute("basket", lstprod);	
				
			}else{
				Hashtable<Product, Integer>  lstprodold  = new Hashtable<Product, Integer>();
				lstprodold = (Hashtable<Product, Integer>) session.getAttribute("basket");
				boolean existFlag = false;
				
				Enumeration<Product> enumKey = lstprodold.keys();
				while(enumKey.hasMoreElements()) {
					Product key = (Product)enumKey.nextElement();
				    
				    if(key.getIdCourse().equals(idCourse)) {
				    	existFlag = true;
				    	Integer val = lstprodold.get(key);
				    	val = val + qty;
				    	if(val>7)
				    		val =7;
				    	
				    	lstprodold.remove(key);
				    	lstprodold.put(key, val);
				    	
				    }
				} 
				if(!existFlag){
					lstprodold.put(p, qty);
				}
				
				
				
				
				request.getSession().setAttribute("basket", lstprodold);
			}
			
			
			
			Hashtable<Product, Integer>  lstprodnew = new Hashtable<Product, Integer>();
			lstprodnew = (Hashtable<Product, Integer>) session.getAttribute("basket");
			
			double total = 0;
		    Enumeration<Product> enumKey1 = lstprodnew.keys();
			while(enumKey1.hasMoreElements()) {
				Product key1 = (Product)enumKey1.nextElement();
				Integer qty1 = lstprodnew.get(key1);
				total += (key1.getPrice())*qty1;
			} 
			
			model.addAttribute("total", total);
			
			model.addAttribute("nbpr", lstprodnew.size());
			model.addAttribute("lstprodnew", lstprodnew);

		return  ("basket");
	}
	
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/saveBasket",method = RequestMethod.POST)
	public String saveBasket(Model model,WebRequest webRequest,HttpSession session, 
			                  final RedirectAttributes redirectAttributes) {
		init();
		if (!util.checkFrontSession(session) == false) {
//			model.addAttribute("nbpr", nbpr);
			User u = (User)session.getAttribute("userFLogin");
			model.addAttribute("user", u);
		}
		Hashtable<Product, Integer>  lstprob =  new Hashtable<Product, Integer>();
		lstprob = (Hashtable<Product, Integer>)session.getAttribute("basket");
		  if(lstprob.size()==0){
			  model.addAttribute("nbpr", lstprob.size());
			  return  ("basket");
		  }
		
		return  ("command_not_register");
		}
	
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/basket",method = RequestMethod.GET)
	public String basket(Model model, HttpSession session)  throws IOException {
		Hashtable<Product, Integer>  lstprodnew = new Hashtable<Product, Integer>();
		lstprodnew = (Hashtable<Product, Integer>) session.getAttribute("basket");
		Integer nbpr = 0;
		if(lstprodnew!=null){
			nbpr =lstprodnew.size();
			double total = 0;
		    Enumeration<Product> enumKey1 = lstprodnew.keys();
			while(enumKey1.hasMoreElements()) {
				Product key1 = (Product)enumKey1.nextElement();
				Integer qty1 = lstprodnew.get(key1);
				total += (key1.getPrice())*qty1;
			} 
			
			model.addAttribute("total", total);
		}
		model.addAttribute("nbpr", nbpr);
		model.addAttribute("lstprodnew", lstprodnew);
		
		
		
	   return ("basket");
	}
	
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/saveCommand_not_register",method = RequestMethod.POST)
	public String saveCommand_not_register(Model model,WebRequest webRequest,HttpSession session, HttpServletRequest request,
			                  final RedirectAttributes redirectAttributes) {
		Hashtable<Product, Integer>  lstprod = new Hashtable<Product, Integer>();
		lstprod = (Hashtable<Product, Integer>) session.getAttribute("basket");
		
//        Integer qty = Integer.valueOf(webRequest.getParameter("qty"));
//        Long idCourse = Long.valueOf(webRequest.getParameter("idCourse"));
//        Product pr = serviceCor.getCourse(idCourse);
        String name = webRequest.getParameter("name");
        String tel = webRequest.getParameter("tel");
        String email = webRequest.getParameter("email");
        String address = webRequest.getParameter("address");
        String city = webRequest.getParameter("city");
		Collection<CommandeLine> listCmdl = null;
		//redirectAttributes.addFlashAttribute("qty", qty);
		Command cmd = new Command(new Date(),name,tel,email,address,city);
		
		init();
		if (!util.checkFrontSession(session) == false) {
			User u = (User)session.getAttribute("userFLogin");
			cmd.setUser(u);
		} 

		serviceCommand.addCommande(cmd);
		Enumeration<Product> enumKey = lstprod.keys();
		while(enumKey.hasMoreElements()) {
			Product pr = (Product)enumKey.nextElement();
			Integer qtity = lstprod.get(pr);
			CommandeLine cmdl = new CommandeLine(qtity,cmd,pr);
			serviceCml.addCommandLine(cmdl);
		} 
		
		
		
		//listCmdl.add(cmdl);
		//cmd.setLstCmdl(listCmdl);
		
		try {
			 HttpSession sessionbasket=request.getSession();  
			 sessionbasket.removeAttribute("basket");
			
			model.addAttribute("command_result", "Ban dat hang thanh cong ");			
		} catch (Exception e) {
			model.addAttribute("command_result", "Dat hang khong thanh cong");		
		}
		
			return  ("command");

	}

	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/del_prod_in_basket", method=RequestMethod.GET)
	public @ResponseBody JsonResponse del(Long idProd, HttpSession session, HttpServletRequest request) {
		    init();
		    Hashtable<Product, Integer>  lstprodold  = new Hashtable<Product, Integer>();
			lstprodold = (Hashtable<Product, Integer>) session.getAttribute("basket");
			
			Enumeration<Product> enumKey = lstprodold.keys();
			while(enumKey.hasMoreElements()) {
				Product key = (Product)enumKey.nextElement();
			    
			    if(key.getIdCourse().equals(idProd)) {
			    	lstprodold.remove(key);
			    }
			} 
			
			request.getSession().setAttribute("basket", lstprodold);
			
            double total = 0;
			Enumeration<Product> enumKey1 = lstprodold.keys();
			while(enumKey1.hasMoreElements()) {
				Product key1 = (Product)enumKey1.nextElement();
				Integer qty1 = lstprodold.get(key1);
				total += (key1.getPrice())*qty1;
			} 
			
			jresp.setStatus(Integer.toString(lstprodold.size()));
			jresp.setResult(total);
			return jresp;
		
	}
	
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/mod_prod_in_basket", method=RequestMethod.GET)
	public @ResponseBody JsonResponse mod(Long idProd,Integer qty, HttpSession session, HttpServletRequest request) {
		    init();
		    Hashtable<Product, Integer>  lstprodold  = new Hashtable<Product, Integer>();
			lstprodold = (Hashtable<Product, Integer>) session.getAttribute("basket");
			Enumeration<Product> enumKey = lstprodold.keys();
			
			while(enumKey.hasMoreElements()) {
				Product key = (Product)enumKey.nextElement();
				
			    if(key.getIdCourse().equals(idProd)) {
			    	lstprodold.remove(key);
			    	lstprodold.put(key, qty);
			    }
			} 
			
			double total = 0;
			
			
			Enumeration<Product> enumKey1 = lstprodold.keys();
			while(enumKey1.hasMoreElements()) {
				Product key1 = (Product)enumKey1.nextElement();
				Integer qty1 = lstprodold.get(key1);
				total += (key1.getPrice())*qty1;
			} 
			
			
			request.getSession().setAttribute("basket", lstprodold);
			
			jresp.setStatus("MOD_SUCCESS");
			jresp.setResult(total);
			return jresp;
		
	}
	
	
	@RequestMapping(value = "/buy_history",method = RequestMethod.GET)
	public ModelAndView buy_history(Model model, HttpSession session)  throws IOException {
		init();
		if (!util.checkFrontSession(session) == false) {
			User u = (User)session.getAttribute("userFLogin");
			List<Command> lstcmd =serviceCommand.listCommandByUserId(u.getIdUser(), 1, 1);
			model.addAttribute("lstcmd", lstcmd);  
			model.addAttribute("nbcm", lstcmd.size());
		}
		else
		  return new ModelAndView("redirect:login");
		
//		<Product, Integer>  lstprodnew = new Hashtable<Product, Integer>();
//		lstprodnew = (Hashtable<Product, Integer>) session.getAttribute("basket");
//		Integer nbpr = 0;
//		if(lstprodnew!=null){
//			nbpr =lstprodnew.size();
//		}
//		model.addAttribute("nbpr", nbpr);
//		model.addAttribute("lstprodnew", lstprodnew);
	   return new ModelAndView("buy_history");
	}
	
	@RequestMapping(value = "/cmd_detail")
	public ModelAndView viewCommand(Long idCom, Model model, HttpSession session) {
		init();
		if (!util.checkFrontSession(session) == true) {
			return new ModelAndView("redirect:login");
		}
		List<CommandeLine> lstcmdl = serviceCml.listCommandLineByCmdId(idCom, 1, 1);
		
		Hashtable<Product, Integer>  lstprod =  new Hashtable<Product, Integer>();
		double total = 0;
		for (CommandeLine lst : lstcmdl) {
			Product pro = lst.getProd();
			Integer qty = lst.getQty();
			lstprod.put(pro, qty);
			total += (pro.getPrice())*qty;
		}
		model.addAttribute("lstcmdl", lstprod);
		model.addAttribute("total", total);
		return new ModelAndView("cmd_detail");
	}
	
	public ModelAndView resolveException(HttpServletRequest request,
			HttpServletResponse response, Object arg2, Exception ex) {
		ModelAndView mv = new ModelAndView();
		mv.addObject("user", new User());
		mv.addObject("exception", ex.getMessage());
		mv.setViewName("user");
		return mv;
	}

}
